package com.ayf.payment.game.api.service;

import com.ayf.payment.game.api.utils.SnowFlakeUtils;
import com.swwx.charm.commons.lang.utils.LogPortal;
import com.swwx.charm.zookeeper.exception.GetLockFailedException;
import com.swwx.charm.zookeeper.exception.ReleaseLockFailedException;
import com.swwx.charm.zookeeper.lock.DistributedLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

/**
 *
 *
 * @author wwl
 * @date 2020/1/16 16:12
 */
@Component
public class ReplacementRepository {

    //public static final long ACCESS_TOKEN_EXPIRED_SECOND = 60L * 60 * 24 * 1;
    public static final long ACCESS_TOKEN_EXPIRED_SECOND = 60L * 60 * 2;
    //public static final long ACCESS_TOKEN_EXPIRED_SECOND = 60L * 5;
    @Autowired
    private RedisTemplate baseRedisTemplate;

    @Autowired
    protected DistributedLock distributedLock;

    private Map mapWhole;
    private Map mapManual=new ConcurrentHashMap<>();
    private Map mapOrder=new ConcurrentHashMap<>();

    public void setWhole(String key,Object value) {
        boolean lock = false;
        String traceId = SnowFlakeUtils.getTraceId();
        String lockName = this.getClass().getSimpleName()+"setWhole".concat(System.getenv("XY_GAME_PAY_LOCK_FLAG"));
        try {
            if (lock = distributedLock.getLock(lockName)) {
                mapWhole= (Map) baseRedisTemplate.opsForValue().get("GATEWAY_WHOLE_DATA");
                if(mapWhole==null){
                    mapWhole=new HashMap<>();
                }
                mapWhole.put(key, value);
                baseRedisTemplate.opsForValue().set("GATEWAY_WHOLE_DATA", mapWhole, ACCESS_TOKEN_EXPIRED_SECOND, TimeUnit.SECONDS);
            }
        } catch (GetLockFailedException e) {
            LogPortal.error("{} >>> [DISTRIBUTED_LOCK_ACQUIRE_FAILED_ZK] 分布式锁获取失败,锁名称为:{}", traceId, lockName);
            LogPortal.error("{} >>> {} 获取lock失败", e, traceId, lockName);
        } catch (Exception e) {
            LogPortal.error("{} >>> {} 任务执行出错 ", e, traceId, lockName);
        } finally {
            if (lock) {
                LogPortal.info(traceId + " >>> " + lockName + " finished.");
                try {
                    distributedLock.releaseLock(lockName);
                } catch (ReleaseLockFailedException e) {
                    LogPortal.error("{} >>> [DISTRIBUTED_LOCK_RELEASE_FAILED_ZK] 分布式锁释放失败,锁名称为:{}", traceId, lockName);
                    LogPortal.error("{} >>> {} 释放失败", e, traceId, lockName);
                }
            }
        }
    }



    public void delWhole(String key) {
        boolean lock = false;
        String traceId = SnowFlakeUtils.getUniqueId();
        String lockName = this.getClass().getSimpleName()+"delWhole".concat(System.getenv("XY_GAME_PAY_LOCK_FLAG"));
        try {
            if (lock = distributedLock.getLock(lockName)) {
                mapWhole= (Map) baseRedisTemplate.opsForValue().get("GATEWAY_WHOLE_DATA");
                mapWhole.remove(key);
                baseRedisTemplate.opsForValue().set("GATEWAY_WHOLE_DATA", mapWhole, ACCESS_TOKEN_EXPIRED_SECOND, TimeUnit.SECONDS);
            }
        } catch (GetLockFailedException e) {
            LogPortal.error("{} >>> [DISTRIBUTED_LOCK_ACQUIRE_FAILED_ZK] 分布式锁获取失败,锁名称为:{}", traceId, lockName);
            LogPortal.error("{} >>> {} 获取lock失败", e, traceId, lockName);
        } catch (Exception e) {
            LogPortal.error("{} >>> {} 任务执行出错 ", e, traceId, lockName);
        } finally {
            if (lock) {
                LogPortal.info(traceId + " >>> " + lockName + " finished.");
                try {
                    distributedLock.releaseLock(lockName);
                } catch (ReleaseLockFailedException e) {
                    LogPortal.error("{} >>> [DISTRIBUTED_LOCK_RELEASE_FAILED_ZK] 分布式锁释放失败,锁名称为:{}", traceId, lockName);
                    LogPortal.error("{} >>> {} 释放失败", e, traceId, lockName);
                }
            }
        }
    }

    public void setManual(String key,Object value){
        mapManual.put(key,value);
        baseRedisTemplate.opsForValue().set("GATEWAY_MANUAL_DATA",mapManual,ACCESS_TOKEN_EXPIRED_SECOND, TimeUnit.SECONDS);
    }

    public void setOrder(String key,Object value){
        mapOrder.put(key,value);
        baseRedisTemplate.opsForValue().set("GATEWAY_ORDER_DATA",mapOrder,ACCESS_TOKEN_EXPIRED_SECOND, TimeUnit.SECONDS);
    }

    public void set(String key,Object value){
        baseRedisTemplate.opsForValue().set(key,value,ACCESS_TOKEN_EXPIRED_SECOND, TimeUnit.SECONDS);
    }
    public Object get(Object key){
        return  baseRedisTemplate.opsForValue().get(key);
    }

    public Set getKeys(String key){
        return  baseRedisTemplate.keys(key);
    }

    public void del(String key){
        baseRedisTemplate.delete(key);
    }

}
